import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 面试题39：数组中出现次数超过一半的数字
 */
public class Offer_39 {
    /**
     * 方法三：Boyer-Moore 投票算法
     * <p>
     * 时间复杂度：O(n)
     * <p>
     * 空间复杂度：O(1)
     */
    public int majorityElement(int[] nums) {
        int ans = nums[0], count = 0;
        for (int num : nums) {
            if (count == 0) {
                ans = num;
                count++;
            } else if (num == ans) {
                count++;
            } else {
                count--;
            }
        }
        return ans;
    }

    /**
     * 方法二：哈希表
     * <p>
     * 时间复杂度：O(n)
     * <p>
     * 空间复杂度：O(n)
     */
    public int majorityElement2(int[] nums) {
        // key 为 nums 中的元素，value 为该元素出现的次数
        Map<Integer, Integer> map = new HashMap<>();
        // 统计每个元素出现的次数
        for (int num : nums) {
            map.put(num, map.getOrDefault(num, 0) + 1);
        }

        // frequency 为最大出现次数
        int frequency = 0, ans = nums[0];
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            if (entry.getValue() > frequency) {
                frequency = entry.getValue();
                ans = entry.getKey();
            }
        }
        return ans;
    }

    /**
     * 方法一：排序
     * <p>
     * 排序后下标为 n/2 元素一定就是「多数元素」
     * <p>
     * 时间复杂度：O(nlogn)
     * <p>
     * 空间复杂度：O(logn)
     */
    public int majorityElement1(int[] nums) {
        Arrays.sort(nums);
        return nums[nums.length / 2];
    }
}
